package com.muyuan.business.strategy.impl;

import com.muyuan.business.domain.TbBusiness;
import com.muyuan.business.strategy.Rule;
import com.muyuan.clues.domain.TbAssignRecord;
import com.muyuan.clues.mapper.SysDictDataMapper;
import com.muyuan.clues.mapper.SysUserMapper;
import com.muyuan.clues.mapper.TbAssignRecordMapper;
import com.muyuan.common.core.domain.entity.SysDictData;
import com.muyuan.common.core.domain.entity.SysUser;
import com.muyuan.common.utils.DateUtils;
import com.muyuan.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * rule 处理策略
 * 1.默认会把转化的线索分配给自己进行跟进。
 */
//配置此处bean的加载，当配置文件中的rule.transfor=rule的时候加载这个bean类
@ConditionalOnProperty(name = "rule.transfor", havingValue = "rule")
@Service("BussinessruleStrategy")
public class RuleStrategy implements Rule {
    //@autowired注解不能注入静态的bean类
    //这里能够成功注入吗？
    @Autowired
    private TbAssignRecordMapper assignRecordMapper;

    //这里能够成功注入吗？
    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysDictDataMapper dictDataMapper;

    private SysUser thisUser = new SysUser();

    /**
     * 参考一下adminStrategy是怎么做的
     */
    /*类的加载
    当Java应用程序启动时，JVM（Java虚拟机）会开始加载类。类加载的过程包括以下几个步骤：
    加载 (Loading): 读取类的二进制字节码文件，生成Class对象。
    验证 (Verification): 确保字节码文件符合JVM规范，例如检查类文件格式、元数据完整性等。
    准备 (Preparation): 为类的静态变量分配内存，并设置默认值。
    解析 (Resolution): 将符号引用转换为直接引用。
    初始化 (Initialization): 执行类的静态初始化块和静态变量的初始化。
    */

    /*Spring 容器的初始化
    Spring容器的初始化过程主要包括以下几个步骤：
    读取配置 (Reading Configuration): Spring容器读取配置文件或注解，解析Bean的定义。
    注册Bean定义 (Registering Bean Definitions): 将Bean定义注册到BeanFactory或ApplicationContext中。
    实例化Bean (Instantiating Beans): 根据Bean定义创建Bean实例。
    依赖注入 (Dependency Injection): 对Bean实例的属性进行依赖注入。
    初始化Bean (Initializing Beans): 调用初始化方法（如@PostConstruct标注的方法、InitializingBean接口的afterPropertiesSet方法或自定义初始化方法）。
    装配Bean (Wiring Beans): 将Bean组装成应用程序。*/

    //静态代码块会在类加载时进行加载，spring容器初始化会在类加载后再进行初始化，然后再对bean对象进行初始化。
    /*static {
        //空间换时间的方式将数据库中的学科读取到内存中
        //预加载学科数据到内存中
        // 获取当前登录的用信息
        String username = SecurityUtils.getUsername();
        //此处会报错，因为类加载过程中，spring中的bean对象还未被初始化所以无法被@autowired注解注入
        SysUser thisUser = userMapper.selectUserByName(username);
    }*/

    //也不能这样改，因为没登陆的话，没有权限,就没法执行SecurityUtils.getUsername()方法来获取登陆的用户名字
    //所以要先登陆后再获取用户信息
    //AdminStrategy之所以能用这种方法是因为它不用获取当前的用户信息，只要分配给admin就行，所以username是固定的admin
    /*@PostConstruct
    public void init(){
        System.out.println("我调用了....");
        // 这里会有bug 没有登录就没有权限
        String username = SecurityUtils.getUsername();
        thisUser = userMapper.selectUserByName(username);
    }*/

    /**
     * 定义一些规则来自动
     *
     * @param tbBusiness
     * @return
     */
    @Override
    public Integer transforBusiness(TbBusiness tbBusiness) {
        //获取Sysuser对象(登录信息)
        String username = SecurityUtils.getUsername();
        SysUser thisUser = userMapper.selectUserByName(username);
        return this.distribute(tbBusiness, thisUser);
    }


    /**
     * 分配商机给具体用户的方法
     * 看我看我！！！！！！！！！！！！！！！
     * 看我能少走弯路！！！！！！！！！！！！
     * 这部分代码没有预设bug，不用研究
     * 该方法主要是将商机分配给具体的人的方法
     *
     * @param business
     * @param user
     * @return
     */
    private int distribute(TbBusiness business, SysUser user) {
        TbAssignRecord tbAssignRecord = new TbAssignRecord();
        tbAssignRecord.setAssignId(business.getId());
        tbAssignRecord.setUserId(user.getUserId());
        tbAssignRecord.setUserName(user.getUserName());
        tbAssignRecord.setDeptId(user.getDeptId());
        tbAssignRecord.setCreateBy(SecurityUtils.getUsername());
        tbAssignRecord.setCreateTime(DateUtils.getNowDate());
        tbAssignRecord.setType(TbAssignRecord.RecordType.BUSNIESS.getValue());
        business.setNextTime(null);
        return assignRecordMapper.insertAssignRecord(tbAssignRecord);
    }

}
